/**
 * <p>Copyright: Copyright (c) 2015</p>
 * <p>Company: Gjfax.com</p>
 */
package com.jy.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;


/**
 * 文件名称： BaseController.java
 * 功能说明：
 * 开发人员： maran
 * 开发时间：2015年7月30日 上午8:47:05
 * 修改记录：修改日期 修改人员 修改说明
 */
public class BaseController {
	
	Logger logger = LoggerFactory.getLogger(BaseController.class);
	
    /**
     * 封装 Map 集合
     * @param request
     * @return
     * @throws UnsupportedEncodingException 
     */
    protected HashMap<String, Object> getParams(HttpServletRequest request){
    	HashMap<String, Object> params = null;
    	try {
    		params = new HashMap<String, Object>();
    		Enumeration<String> paraNames = request.getParameterNames();
    		for(Enumeration<String> e = paraNames; e.hasMoreElements();){
    			String key = e.nextElement().toString();
    			String value = request.getParameter(key);
    			params.put(key, value);
    		}
    		int p = 1;
    		try {
    			p = request.getParameter("p") == null ? 1 : Integer.parseInt(request.getParameter("p")) <= 0 ? 1 : Integer.parseInt(request.getParameter("p"));
    		} catch (Exception e) {
    			// TODO: handle exception
    			p = 1;
    		}
    		params.put("p", p);
		} catch (Exception e) {
			e.printStackTrace();
		}
        return params;
    }
    
    /**
     * 封装 Map 集合
     * @param request
     * @return
     */
    protected HashMap<String, Object> getParams(HttpServletRequest request, boolean isFlag) {
        HashMap<String, Object> params = new HashMap<String, Object>();
        Enumeration<String> paraNames = request.getParameterNames();
        for(Enumeration<String> e = paraNames; e.hasMoreElements();){
           String key = e.nextElement().toString();
           String value = "";
           try {
        	   	value = request.getParameter(key);
        	   	value = URLDecoder.decode(value, "UTF-8");
		   } catch (UnsupportedEncodingException e1) {
				value = request.getParameter(key); 
		   }
           params.put(key, value);
        }
        int p = 1;
		try {
			p = request.getParameter("p") == null ? 1 : Integer.parseInt(request.getParameter("p")) <= 0 ? 1 : Integer.parseInt(request.getParameter("p"));
		} catch (Exception e) {
			// TODO: handle exception
			p = 1;
		}
		params.put("p", p);
        return params;
    }
    
    
    /**
	 * 文件下载(单个文件)
	 * 		修改时间				修改人		备注
	 * 		2016年5月11日14:48:56	maran		支持断点下载
	 * 
	 * @param fileName
	 * @param filePath
	 * @param request
	 * @param response
	 * @return
	 */
	protected String downloadFile(String fileName, String filePath, HttpServletRequest request, HttpServletResponse response) {
		response.setCharacterEncoding("utf-8");  
        response.setContentType("application/x-download");    
        response.setHeader("Accept-Ranges", "bytes");    
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        
        BufferedInputStream bis = null;
		try {
			String url = PropertiesUtil.getProperty(filePath);
			String path = request.getSession().getServletContext().getRealPath(url);
			String location = path + File.separator + fileName;
			
			File file = new File(path + File.separator + fileName);
			if (file.exists()) {
	            long p = 0L;
	            long toLength = 0L;
	            long contentLength = 0L;
	            int rangeSwitch = 0; // 0,从头开始的全文下载；1,从某字节开始的下载（bytes=27000-）；2,从某字节开始到某字节结束的下载（bytes=27000-39000）
	            long fileLength;
	            String rangBytes = "";
	            fileLength = file.length();
	 
	            // get file content
	            InputStream ins = new FileInputStream(file);
	            bis = new BufferedInputStream(ins);
	 
	            // tell the client to allow accept-ranges
	            response.reset();
	            response.setHeader("Accept-Ranges", "bytes");
	 
	            // client requests a file block download start byte
	            String range = request.getHeader("Range");
	            if (range != null && range.trim().length() > 0 && !"null".equals(range)) {
	                response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
	                rangBytes = range.replaceAll("bytes=", "");
	                if (rangBytes.endsWith("-")) {  // bytes=270000-
	                    rangeSwitch = 1;
	                    p = Long.parseLong(rangBytes.substring(0, rangBytes.indexOf("-")));
	                    contentLength = fileLength - p;  // 客户端请求的是270000之后的字节（包括bytes下标索引为270000的字节）
	                } else { // bytes=270000-320000
	                    rangeSwitch = 2;
	                    String temp1 = rangBytes.substring(0, rangBytes.indexOf("-"));
	                    String temp2 = rangBytes.substring(rangBytes.indexOf("-") + 1, rangBytes.length());
	                    p = Long.parseLong(temp1);
	                    toLength = Long.parseLong(temp2);
	                    contentLength = toLength - p + 1; // 客户端请求的是 270000-320000 之间的字节
	                }
	            } else {
	                contentLength = fileLength;
	            }
	 
	            // 如果设设置了Content-Length，则客户端会自动进行多线程下载。如果不希望支持多线程，则不要设置这个参数。
	            // Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]
	            response.setHeader("Content-Length", new Long(contentLength).toString());
	 
	            // 断点开始
	            // 响应的格式是:
	            // Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
	            if (rangeSwitch == 1) {
	                String contentRange = new StringBuffer("bytes ").append(new Long(p).toString()).append("-").append(new Long(fileLength - 1).toString()).append("/").append(new Long(fileLength).toString()).toString();
	                response.setHeader("Content-Range", contentRange);
	                bis.skip(p);
	            } else if (rangeSwitch == 2) {
	                String contentRange = range.replace("=", " ") + "/" + new Long(fileLength).toString();
	                response.setHeader("Content-Range", contentRange);
	                bis.skip(p);
	            } else {
	                String contentRange = new StringBuffer("bytes ").append("0-").append(fileLength - 1).append("/").append(fileLength).toString();
	                response.setHeader("Content-Range", contentRange);
	            }
	 
	            fileName = file.getName();
	            response.setContentType("application/octet-stream");
	            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
	 
	            OutputStream out = response.getOutputStream();
	            int n = 0;
	            long readLength = 0;
	            int bsize = 1024;
	            byte[] bytes = new byte[bsize];
	            if (rangeSwitch == 2) {
	                // 针对 bytes=27000-39000 的请求，从27000开始写数据                    
	                while (readLength <= contentLength - bsize) {
	                    n = bis.read(bytes);
	                    readLength += n;
	                    out.write(bytes, 0, n);
	                }
	                if (readLength <= contentLength) {
	                    n = bis.read(bytes, 0, (int) (contentLength - readLength));
	                    out.write(bytes, 0, n);
	                }                   
	            } else {
	                while ((n = bis.read(bytes)) != -1) {
	                    out.write(bytes,0,n);                                                      
	                }                   
	            }
	            out.flush();
	            out.close();
	            bis.close();
	        } else {
	            if (logger.isDebugEnabled()) {
	                logger.debug("Error: file " + location + " not found.");
	            }                
	        }
	    } catch (IOException ie) {
	        // 忽略 ClientAbortException 之类的异常
	    } catch (Exception e) {
	        logger.error("文件下载失败" + e);
	    }
		return null;
	}
	
}
